#include "json_utils.h"
#include <regex>
#include <algorithm>

namespace yquote {

std::string JsonUtils::quoteToJson(const QuoteData& quote) {
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(2);
    
    oss << "{"
        << "\"symbol\":\"" << escapeJson(quote.symbol) << "\","
        << "\"price\":" << quote.price << ","
        << "\"open\":" << quote.open << ","
        << "\"high\":" << quote.high << ","
        << "\"low\":" << quote.low << ","
        << "\"close\":" << quote.close << ","
        << "\"volume\":" << quote.volume << ","
        << "\"change\":" << quote.change << ","
        << "\"change_percent\":" << quote.change_percent << ","
        << "\"timestamp\":\"" << timestampToString(quote.timestamp) << "\""
        << "}";
    
    return oss.str();
}

std::string JsonUtils::quotesToJson(const std::vector<QuoteData>& quotes) {
    std::ostringstream oss;
    oss << "[";
    
    for (size_t i = 0; i < quotes.size(); ++i) {
        if (i > 0) oss << ",";
        oss << quoteToJson(quotes[i]);
    }
    
    oss << "]";
    return oss.str();
}

std::vector<std::string> JsonUtils::parseSubscribeRequest(const std::string& json) {
    std::vector<std::string> symbols;
    
    try {
        // 查找action字段
        std::string action = extractStringValue(json, "action");
        if (action != "subscribe" && action != "unsubscribe") {
            return symbols; // 返回空数组表示解析失败
        }
        
        // 提取symbols数组
        symbols = extractStringArray(json, "symbols");
    } catch (const std::exception&) {
        // 解析失败，返回空数组
        symbols.clear();
    }
    
    return symbols;
}

std::string JsonUtils::createErrorResponse(const std::string& error, const std::string& message) {
    return "{\"status\":\"error\",\"error\":\"" + escapeJson(error) + 
           "\",\"message\":\"" + escapeJson(message) + "\"}";
}

std::string JsonUtils::createSuccessResponse(const std::string& message) {
    return "{\"status\":\"success\",\"message\":\"" + escapeJson(message) + "\"}";
}

std::string JsonUtils::createHeartbeat() {
    return "{\"type\":\"heartbeat\",\"timestamp\":\"" + 
           timestampToString(std::chrono::system_clock::now()) + "\"}";
}

std::string JsonUtils::timestampToString(const std::chrono::system_clock::time_point& tp) {
    auto time_t = std::chrono::system_clock::to_time_t(tp);
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
        tp.time_since_epoch()) % 1000;
    
    std::ostringstream oss;
    oss << std::put_time(std::gmtime(&time_t), "%Y-%m-%dT%H:%M:%S");
    oss << '.' << std::setfill('0') << std::setw(3) << ms.count() << 'Z';
    
    return oss.str();
}

std::string JsonUtils::escapeJson(const std::string& input) {
    std::string output;
    output.reserve(input.length());
    
    for (char c : input) {
        switch (c) {
            case '"': output += "\\\""; break;
            case '\\': output += "\\\\"; break;
            case '\b': output += "\\b"; break;
            case '\f': output += "\\f"; break;
            case '\n': output += "\\n"; break;
            case '\r': output += "\\r"; break;
            case '\t': output += "\\t"; break;
            default:
                if (c >= 0 && c < 32) {
                    output += "\\u";
                    output += "0000";
                    std::sprintf(&output[output.length()-2], "%02x", c);
                } else {
                    output += c;
                }
                break;
        }
    }
    
    return output;
}

std::string JsonUtils::extractStringValue(const std::string& json, const std::string& key) {
    std::regex pattern("\"" + key + "\"\\s*:\\s*\"([^\"]+)\"");
    std::smatch match;
    
    if (std::regex_search(json, match, pattern)) {
        return match[1].str();
    }
    
    return "";
}

std::vector<std::string> JsonUtils::extractStringArray(const std::string& json, const std::string& key) {
    std::vector<std::string> result;
    
    // 查找数组开始位置
    std::regex array_pattern("\"" + key + "\"\\s*:\\s*\\[([^\\]]+)\\]");
    std::smatch array_match;
    
    if (std::regex_search(json, array_match, array_pattern)) {
        std::string array_content = array_match[1].str();
        
        // 提取数组中的字符串元素
        std::regex string_pattern("\"([^\"]+)\"");
        std::sregex_iterator iter(array_content.begin(), array_content.end(), string_pattern);
        std::sregex_iterator end;
        
        for (; iter != end; ++iter) {
            result.push_back((*iter)[1].str());
        }
    }
    
    return result;
}

} // namespace yquote 